#include "test_common.hpp"

TEST_CASE("rdtree select", "[rdtree]")
{
  sqlite3 * db = nullptr;
  test_db_open(&db);

  int rc = sqlite3_exec(
      db, 
      "CREATE VIRTUAL TABLE xyz USING rdtree(id integer primary key, s bits(1024))",
      NULL, NULL, NULL);
  REQUIRE(rc == SQLITE_OK);

  // insert some binary fingerprints
  sqlite3_stmt *pStmt = nullptr;
  rc = sqlite3_prepare(db, "INSERT INTO xyz(id, s) VALUES(?1, bfp_dummy(1024, ?2))", -1, &pStmt, 0);
  REQUIRE(rc == SQLITE_OK);

  for (int i=0; i < 256; ++i) {
    rc = sqlite3_bind_int(pStmt, 1, i+1);
    REQUIRE(rc == SQLITE_OK);

    rc = sqlite3_bind_int(pStmt, 2, i);
    REQUIRE(rc == SQLITE_OK);

    rc = sqlite3_step(pStmt);
    REQUIRE(rc == SQLITE_DONE);

    rc = sqlite3_reset(pStmt);
    REQUIRE(rc == SQLITE_OK);
  }

  SECTION("select matching simple subset constraints") {
    
    // if we use 0x01 as subset match constraint, it will return all the dummy bfp 
    // records generated by an odd number. we therefore expect the number of these
    // records to be a half of the total
    test_select_value(
      db, 
      "SELECT COUNT(*) FROM xyz WHERE id MATCH rdtree_subset(bfp_dummy(1024, 1))", 128);

    // if we instead use 0x0f, the fingerprints matching this pattern as subset are those
    // that vary in value of the more significant nibble (0x0f, 0x1f, ... 0xff). there should
    // be 16 such fingerprints
    test_select_value(
      db, 
      "SELECT COUNT(*) FROM xyz WHERE id MATCH rdtree_subset(bfp_dummy(1024, 0x0f))", 16);
  }

  SECTION("select matching simple similarity constraints") {
    
    // if we use 0x01 as similarity match constraint, with a threshold of at least 0.5
    // we should get 0x01 (perfect match) and the bfps with two bits set per byte where 
    // one of the bits is 0x01 (7 more values). the expected number of returned values
    // is therefore 8
    test_select_value(
      db, 
      "SELECT COUNT(*) FROM xyz WHERE bfp_tanimoto(bfp_dummy(1024, 1), s) >= 0.5", 8);
    
    test_select_value(
      db, 
      "SELECT COUNT(*) FROM xyz WHERE id MATCH rdtree_tanimoto(bfp_dummy(1024, 1), .5)", 8);
  }

  sqlite3_finalize(pStmt);

  rc = sqlite3_exec(db, "DROP TABLE xyz", NULL, NULL, NULL);
  REQUIRE(rc == SQLITE_OK);

  test_db_close(db);
}
